<script>
//Map of all opened tabs keyed by tabId
var allOpenTabs = {};
//Map of recently closed tabs keyed by timestamp
var rcts;
//Array of RCT timestamps
var rctTimestamps = [];
//Array of URL blacklist filters
var filters;
//Maximum number of rcts shown on popup page
var maxPopupLengthDefault = 15;
var maxPopupLength;
//Configuration of the extension
var extensionConfig;
//true if tabShots should be shown/saved
var showTabShot;
//maxNumberOfStoredRcts
var maxNumberOfStoredRctsDefault = 30;
var maxNumberOfStoredRcts;

//Loads the values for the extension.
//Fetches the extension configuration
fetchExtensionConfig();
//Fetches the filters.
fetchFilters();
//Fetches the maxPopupLength.
fetchMaxPopupLength();
//Fetches the maxNumberOfStoredRcts.
fetchMaxNumberOfStoredRcts();
//Fetches the recentlyClosedTabs.
fetchRcts();
//Fetches the flag for showing the tabShot.
fetchShowTabShot();

//Gets all open windows.
chrome.tabs.getAllInWindow(null, function(tabs){
  for (var key in tabs) {
	// TODO was machen, wenn key == undefined???
    allOpenTabs[tabs[key].id] = tabs[key];
    if (showTabShot == 'true') {
      setImgDataUrl(tabs[key].id);
    }
  }
});

//Listener on update.
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
  if (changeInfo.status == 'complete') {
    if (tab === undefined) return;
    allOpenTabs[tabId] = tab;
    if (showTabShot == 'true') {
      setImgDataUrl(tabId);
    }
  }
});

//Listener on remove.
chrome.tabs.onRemoved.addListener(function(tabId) {
  var tabInfo = allOpenTabs[tabId];
  if (tabInfo == undefined) return;
  
  delete allOpenTabs[tabId];
  
  // TODO delete all rcts on all chrome windows closed event
  // var windowsCounter = 0;
  // var tabsCounter = 0;
  // chrome.windows.getAll(null, function(windows) {
  //   windowsCounter = windows.length;
  // })
  // tabsCounter = allOpenTabs.length;
  // if(tabsCounter == 1 && windowsCounter == 1) {
  //   storeRcts({});
  // }
  
  if (shouldBeIgnored(tabInfo.url)) return;
  
  var timestamp = (new Date()).getTime();
  rcts[timestamp] = tabInfo;
  rctTimestamps.unshift(timestamp);
  
  storeRcts(rcts);
  
  //delete all rcts within the latest rct until maxNumberOfStoredRcts
  for (var i = 0; i <= rctTimestamps.length; i++){
    if (maxNumberOfStoredRcts <= rctTimestamps.length) {
      var deleteTimestamp = rctTimestamps[rctTimestamps.length - 1];
      rctTimestamps.splice(rctTimestamps.length - 1, 1);
      removeRctByTimestamp(deleteTimestamp);
    } else if (maxNumberOfStoredRcts > rctTimestamps.length) {
      break;
    }
  }
});

//Listener onSelectionChanged
chrome.tabs.onSelectionChanged.addListener(function(tabId) {
  if (showTabShot == 'true') {
    setImgDataUrl(tabId);
  }
});

//Fetches the extension configuration
function fetchExtensionConfig() {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', chrome.extension.getURL('manifest.json'), false);
  xhr.onreadystatechange = function() {
    if (this.readyState == 4) {
      extensionConfig = JSON.parse(this.responseText);
      var newVersion = (extensionConfig.version).split(/\./g);
      var storedVersion = localStorage['version'];
      if (storedVersion !== undefined) {
	      var oldVersion = (storedVersion).split(/\./g);
	      for (var i = 0; i < 2; i++) {
	        if ((newVersion[i] != oldVersion[i])) {
		        //alert('Neue Version!');
	          chrome.tabs.create( {'url' : chrome.extension.getURL('infonews.html'), 'selected' : true}, function(tab) {});
	          break;
	        }
	      }
	      if (extensionConfig.version != storedVersion) {
	        localStorage.setItem('version', extensionConfig.version);
	      }
      }
	  }
  };
  xhr.send();
}

//Fetches/Initialises the rcts from the localStorage.
function fetchRcts() {
  var rctsString = localStorage['recentlyClosedTabs'];
  if (rctsString === undefined) {
    storeRcts({});
    rctTimestamps = [];
  } else {
    rcts = JSON.parse(rctsString);
    //TODO muss das sein?
    rctTimestamps = [];
    for (var timestamp in rcts) rctTimestamps.unshift(timestamp);
  }
}

//Modifys/Persists the rcts to the localStorage.
//@param newRecentlyClosedTabs recentlyClosedTabs object to store in the localStorage
function storeRcts(newRcts) {
	if (newRcts !== undefined)
	  rcts = newRcts;
	localStorage.setItem('recentlyClosedTabs', JSON.stringify(rcts));
}

//Removes a rct by index.
//@param i index of the element to be removed from the recentlyClosedTabs
function removeRctByTimestamp(timestamp) {
	delete rcts[timestamp];
	for (var index in rctTimestamps) if (rctTimestamps[index] == timestamp) rctTimestamps.splice(index, 1);
	storeRcts();
}

//Function defining the filter-object.
//@param url url to filter
function filter(url) {
  this.url = url;
}

//Fetches/Initialises the filters from the localStorage.
function fetchFilters() {
  var filterString = localStorage['filters'];
  if (filterString === undefined) {
    filters = {};
    filters[0] = new filter('chrome://newtab/');
    filters[1] = new filter('about:blank');
    storeFilters();
  } else {
    filters = JSON.parse(filterString);
    for (var i in filters)
      if (filters[i] == null || filters[i] === undefined)
        filters.splice(i, 1);
  }
}

//Modifys/Persists the filters to the localStorage
//@param newFilters filters object to store in the localStorage
function storeFilters(newFilters) {
	if (newFilters !== undefined)
	  filters = newFilters;
	localStorage.setItem('filters', JSON.stringify(filters));
}

//Adds url to the filters.
//@param url url to be added
function addUrlToFilters(url) {
	var timestamp = (new Date()).getTime();
	filters[timestamp] = new filter(url);
	storeFilters();
}

//Checks if given url is already in the filters.
//@param url url to be checked if already in the filters then false, if not true.
function isFilterUnique(url) {
	for (var timestamp in filters) {
	  if (filters[timestamp].url == url) return false;
	}
	return true;
}

//Adds url to the filters if url is unique.
//@ param url url to be added
function addUrlToFiltersAndCheck(url) {
	if (isFilterUnique(url)) {
	  addUrlToFilters(url);
	} else {
	  alert('"' + url + '" not added to the filters. The url is already in the filters.');
	}
}

//Fetches/Initialises the maxPopupLength from the localStorage.
function fetchMaxPopupLength() {
  maxPopupLength = localStorage['maxPopupLength'];
  if (maxPopupLength === undefined)
    storeMaxPopupLength(maxPopupLengthDefault);
}
// Modifys/Persists the maxPopupLength to the localStorage.
// @am newMaxPopupLength maxPopupLength to store in the localStorage
function storeMaxPopupLength(newMaxPopupLength) {
  maxPopupLength = newMaxPopupLength;
  localStorage.setItem('maxPopupLength', maxPopupLength);
}

//Fetches/Initialises the maxPopupLength from the localStorage.
function fetchMaxNumberOfStoredRcts() {
  maxNumberOfStoredRcts = localStorage['maxNumberOfStoredRcts'];
  if (maxNumberOfStoredRcts === undefined)
    storeMaxNumberOfStoredRcts(maxNumberOfStoredRctsDefault);
}
//Modifys/Persists the maxNumberOfStoredRcts to the localStorage.
//@am newMaxNumberOfStoredRcts maxNumberOfStoredRcts to store in the localStorage
function storeMaxNumberOfStoredRcts(newMaxNumberOfStoredRcts) {
  maxNumberOfStoredRcts = newMaxNumberOfStoredRcts;
  localStorage.setItem('maxNumberOfStoredRcts', maxNumberOfStoredRcts);
}

//Adds a zero to the beginning of a number if it is a single letter number.
//@param number number to pad
//@return padded number with leading 0 if it is a single letter number
function pad2(number) {
  return (number < 10 ? '0' : '') + number;
}

var month = new Array(12);
month[0] = "January";
month[1] = "February";
month[2] = "March";
month[3] = "April";
month[4] = "May";
month[5] = "June";
month[6] = "July";
month[7] = "August";
month[8] = "September";
month[9] = "October";
month[10] = "November";
month[11] = "December";

var monthShort = new Array(12);
monthShort[0] = "Jan";
monthShort[1] = "Febr";
monthShort[2] = "Mar";
monthShort[3] = "Apr";
monthShort[4] = "May";
monthShort[5] = "Jun";
monthShort[6] = "Jul";
monthShort[7] = "Aug";
monthShort[8] = "Sep";
monthShort[9] = "Oct";
monthShort[10] = "Nov";
monthShort[11] = "Dec";

//Gets the date and time as string.
//@param timestamp id of the recently closed tabs element
//@return timeString if date == today, else dateString and timeString
function getDateString(timestamp) {
	var date = new Date();
	date.setTime(timestamp);
	var today = new Date();
	// German layout
	// var dateString = date.getDate() + ". " + monthShort[date.getMonth()];
	// English layout
	var dateString = monthShort[date.getMonth()] + " " + date.getDate();
	var timeString = pad2(date.getHours()) + ":" + pad2(date.getMinutes());
	if (date.getDate() == today.getDate() && date.getMonth() == today.getMonth() && date.getFullYear() == today.getFullYear()) {
		return timeString;
	} else {
		return dateString;
	}
}

//Gets the date and time as string.
//@param timestamp id of the recently closed tabs element
//@return timeString for the detailed date popup
function getDateStringDetail(timestamp) {
var date = new Date();
date.setTime(timestamp);
var dateString =  (date.getMonth() + 1) + "/" + date.getDate() + "/" + date.getFullYear();
var timeString = pad2(date.getHours()) + ":" + pad2(date.getMinutes());
return dateString  + " " + timeString;
}

// Checks if the given object is empty.
// @param obj object to be checked
function isEmpty(obj){
  for(var i in obj){ 
    if(obj.hasOwnProperty(i)){return false;}
  }
  return true;
}

//Returns true if the filters contain the given url else false.
//@param url url to check if it is in the filters object
function shouldBeIgnored(url) {
	if (url === undefined)
	  return true;
	for (key in filters)
	  if (url == filters[key].url)
	    return true;
  return false;
}

//Shows prompt with title and url to edit.
//@param title title of prompt
//@param url   url to be shown for edit purposes
//@return edited url
function showPrompt(title, url) {
  return prompt(title, url);
}

//Shows confirmation with text.
//@return true if ok is pressed, else false
function showConfirm(text) {
  return confirm(text);
}

//Fetches/Initialises the showTabShot from the localStorage.
function fetchShowTabShot() {
  showTabShot = localStorage['showTabShot'];
  if (showTabShot === undefined)
    storeShowTabShot('false');
}

// Modifys/Persists the showTabShot to the localStorage.
// @param newShowTabShot showTabShot to store in the localStorage
function storeShowTabShot(newShowTabShot) {
  showTabShot = newShowTabShot;
  localStorage.setItem('showTabShot', showTabShot);
}

var orgImage = new Image();
var canvas = document.createElement('canvas');
// Puts the dataUrl of the tab specified by the given tabId into the object allOpenedTabs.
// @param tabId id of the tab to set the image for
function setImgDataUrl(tabId) {
  if (allOpenTabs[tabId] !== undefined)
    chrome.tabs.captureVisibleTab(
      allOpenTabs[tabId].windowId,
      function(snapshotData) {
        // console.log("receiving snapshot data for tabId = " + tabId);
        orgImage.onload = function() {
          // console.log("orgImage size = " + orgImage.width + "x" + orgImage.height);
          var newHeight = 110;
          var newWidth = orgImage.width * newHeight / orgImage.height;
          // Create a canvas with the desired dimensions
          canvas.width = newWidth + 10;
          canvas.height = newHeight + 10;
          var context = canvas.getContext("2d");

          // Scale and draw the source image to the canvas
          context.drawImage(orgImage, 5, 5, newWidth, newHeight);

          // Convert the canvas to a data URL in PNG format
          allOpenTabs[tabId].tabShot = canvas.toDataURL();

          // Check the result
          // var chkImage = new Image();
          // chkImage.onload = function() {
          // console.log("chkImage size = " + chkImage.width + "x" + chkImage.height); }
          // chkImage.src = allOpenTabs[tabId].tabShot;
        }
        orgImage.src = snapshotData;
      });
}
</script>